/*
 * @Author: your name
 * @Date: 2021-01-28 10:24:56
 * @LastEditTime: 2021-04-19 11:20:54
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \tower_defense\assets\scripts\game_scene\tower\arrow_tower.ts
 */

import { ArrowTowerParams } from "../../game_data/tower_data/arrow_tower_params";
import { UG } from "../../modules/ugame";
import { FrameAnim } from "../../common/frame_anim";

const { ccclass, property } = cc._decorator;

// 自定义类
@ccclass("arrow_tower_skin")
class arrow_tower_skin {
    @property(cc.SpriteFrame)
    public tower_bg: cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    public up_idle: cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    public down_idle: cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    public up_frames: cc.SpriteFrame[] = [];

    @property(cc.SpriteFrame)
    public down_frames: cc.SpriteFrame[] = [];

    @property(cc.Integer)
    public man_ypos = 29;
}

@ccclass
export class ArrowTower extends cc.Component {

    @property(cc.Integer)   // 弓箭塔级别 1 2 3 4
    public tower_level: number = 1;

    @property({             // 弓箭塔每个等级的皮肤
        type: arrow_tower_skin,
    })
    public level_tower_skin = [];

    @property(cc.Integer)   // 动画播放间隔
    public anim_duration = 0.1;

    @property(cc.Prefab)    // 子弹预制体
    public arrow_bullet_pre: cc.Prefab = null;

    @property(cc.Node)      // 左弓箭手
    public l_archer: cc.Node = null;
    @property(cc.Node)      // 右弓箭手
    public r_archer: cc.Node = null;

    @property(cc.Graphics)
    public graphics: cc.Graphics = null;

    public bullet_root_node: cc.Node = null;    // 子弹存放节点
    public is_debug: boolean = true;           // 是否开启塔攻击范围绘制
    public tower_center_pos: cc.Vec2 = cc.v2();     // 塔中心坐标

    public l_archer_frame_anim: FrameAnim = null;      // 左弓箭手帧动画组件
    public r_archer_frame_anim: FrameAnim = null;      // 右弓箭手帧动画组件
    public current_l_archer_flag: boolean = false;     // 当前射箭是否为左弓箭手

    public tower_center_pos_in_tower_panel: cc.Vec2 = null; // tower_panel坐标系下的塔中心节点

    start() {
        this.scheduleOnce(this.arrow_tower_ai.bind(this), 0.1);
    }

    onLoad() {
        // this.is_debug = true;

        this.bullet_root_node = cc.find('Canvas/tower_panel/bullet_root');

        // 获取塔中心坐标
        this.tower_center_pos = this.get_tower_center_pos();

        // 开启debug
        // this._draw_tower_debug();
        
        // 给左弓箭手绑定自定义动画组件
        this.l_archer_frame_anim = this.l_archer.addComponent(FrameAnim);
        this.l_archer_frame_anim.sprite_com = this.l_archer.getComponent(cc.Sprite);
        this.l_archer_frame_anim.anim_com = this.l_archer.getComponent(cc.Animation);
        // 给右弓箭手绑定自定义动画组件
        this.r_archer_frame_anim = this.r_archer.addComponent(FrameAnim);
        this.r_archer_frame_anim.sprite_com = this.r_archer.getComponent(cc.Sprite);
        this.r_archer_frame_anim.anim_com = this.r_archer.getComponent(cc.Animation);
    }

    // 获取塔等级
    public get_tower_level(): any {
        if (this.tower_level >= 4) {
            // 防御塔已经是最高级
            return true;
        } else {
            return this.tower_level;
        }
    }

    // 调整弓箭手精灵图片
    private _set_archer_sprite(archer: cc.Node, dir: number): void {
        // 0 向上, 1 向下
        let archer_sprite: cc.Sprite = archer.getComponent(cc.Sprite);
        if (dir === 0) {
            archer_sprite.spriteFrame = this.level_tower_skin[this.tower_level - 1].up_idle;
        } else {
            archer_sprite.spriteFrame = this.level_tower_skin[this.tower_level - 1].down_idle;
        }
    }

    // 根据等级设置弓箭塔图片
    private _set_tower_skin_by_level(): void {
        // 调整弓箭手位置
        this.l_archer.y = this.level_tower_skin[this.tower_level - 1].man_ypos;
        this.r_archer.y = this.level_tower_skin[this.tower_level - 1].man_ypos;

        // 调整塔精灵图片
        let tower_sprite: cc.Sprite = this.node.getComponent(cc.Sprite);
        tower_sprite.spriteFrame = this.level_tower_skin[this.tower_level - 1].tower_bg;

        // 调整弓箭手精灵图片
        this._set_archer_sprite(this.l_archer, 0);
        this._set_archer_sprite(this.r_archer, 0);
    }

    // 升级塔
    public upgrade_tower(): any {
        // 弓箭塔有4个等级
        if (this.tower_level >= 4) {
            cc.log("已经最高级");
            return true;
        }

        // 开启debug
        this._draw_tower_debug();

        this.tower_level++;
        // 根据等级设置弓箭塔精灵
        this._set_tower_skin_by_level();

        return this.tower_level;
    }

    // 获取塔中心位置
    public get_tower_center_pos(): cc.Vec2 {
        let center_pos: cc.Vec2 = this.node.getPosition();
        
        let _a: cc.Vec2 = this.node.parent.convertToWorldSpaceAR(this.tower_center_pos);   // 转为世界坐标
        let _b: cc.Vec2 = this.node.parent.parent.convertToNodeSpaceAR(_a);

        this.tower_center_pos_in_tower_panel = _b;

        // this.graphics.circle(_b.x, _b.y, 5);
        // this.graphics.fill();

        return center_pos;
    }

    // 绘制塔攻击范围
    private _draw_tower_debug(): void {
        if (!this.is_debug) {
            return;
        }
        // 先清除
        this.graphics.clear();
        // 搜索半径
        let search_r: number = ArrowTowerParams[this.tower_level - 1].search_R;
        // 绘制
        const _b: cc.Vec2 = this.tower_center_pos_in_tower_panel;
        this.graphics.circle(_b.x, _b.y, search_r);
        this.graphics.stroke();
    }

    // ===================================== 塔行为 ========================================
    // 弓箭手射击动画
    private _archer_shoot_anim(archer: cc.Node, enemy_world_pos: cc.Vec2): void {
        // 获取帧动画组件,
        let archer_frame_anim: FrameAnim = archer.getComponent("frame_anim");
        archer_frame_anim.sample = 1;
        if (!archer_frame_anim) {
            archer_frame_anim = archer.addComponent(FrameAnim);
        }
        // 计算方向
        let archer_world_pos: cc.Vec2 = archer.parent.convertToWorldSpaceAR(cc.v2(archer.x, archer.y));// 在塔父节点中，把弓箭手坐标转为世界坐标
        let dir: cc.Vec2 = enemy_world_pos.sub(archer_world_pos);
        // 判断弓箭手动画 >0 朝上 <0 朝下
        let _dir_num: number = 0;
        if (dir.y > 0) {
            archer_frame_anim.sprite_frame_arr = this.level_tower_skin[this.tower_level - 1].up_frames;
            _dir_num = 0;
        } else {
            archer_frame_anim.sprite_frame_arr = this.level_tower_skin[this.tower_level - 1].down_frames;
            _dir_num = 1;
        }
        archer_frame_anim.sample = this.anim_duration;
        // 播放一次动画
        archer_frame_anim.play_once(() => {
            // 播放完成后,恢复弓箭手精灵图片
            this._set_archer_sprite(archer, _dir_num);
        });

        // 发射子弹
        let search_r: number = ArrowTowerParams[this.tower_level - 1].search_R;
        let enemy: cc.Node = UG.search_enemy(this.tower_center_pos, search_r);
        // 生成子弹,发射到目标地点
        let bullet: cc.Node = cc.instantiate(this.arrow_bullet_pre);
        bullet.parent = this.bullet_root_node;
        bullet.active = true;
        bullet.getComponent("arrow_bullet").shoot(this.tower_level, archer_world_pos, enemy_world_pos, enemy);
    }

    // 射击
    public shoot_anim(enemy_world_pos: cc.Vec2): void {
        // 弓箭手交替射击
        if (!this.current_l_archer_flag) {
            this._archer_shoot_anim(this.r_archer, enemy_world_pos);
        } else {
            this._archer_shoot_anim(this.l_archer, enemy_world_pos);
        }
        // 重置flag
        this.current_l_archer_flag = !this.current_l_archer_flag;
    }

    // 塔AI
    public arrow_tower_ai(): void {
        if (!this.tower_center_pos) {
            this.tower_center_pos = this.get_tower_center_pos();
        }
        // 获取塔中心位置
        let center_pos: cc.Vec2 = this.tower_center_pos;
        // 搜索半径
        let search_r = ArrowTowerParams[this.tower_level - 1].search_R;
        // 扫描时间间隔
        let time: number = 0.1;
        // 攻击敌人
        let enemy: cc.Node = UG.search_enemy(center_pos, search_r);
        if (enemy) {
            // cc.log('找到敌人');
            let _enemy_world_pos: cc.Vec2 = enemy.parent.convertToWorldSpaceAR(cc.v2(enemy.x, enemy.y));   // 再敌人的父节点中，把敌人转为世界坐标
            // 播放射击动画
            this.shoot_anim(_enemy_world_pos);
            time = 1;
        }
        this.scheduleOnce(this.arrow_tower_ai.bind(this), time);
    }
}